"""
    机器学习：算法
        1、K-means将数据分群：
            目的：
                k-平均聚类的目的是：把n个点（可以是样本的一次观察或一个例项）划分到k个聚类中，是的每个
            点都属于最近的均值（此即聚类中心）对应的聚类，以之作为聚类的标准
            应用：
                非监督模型

"""
from __future__ import print_function, division
# %matplotlib inline
import seaborn as sns
import matplotlib.pyplot as plt

from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession
from pyspark.mllib.clustering import KMeans, KMeansModel
from pyspark.sql import SparkSession

from numpy import array
from math import sqrt

spark = SparkSession.builder.master("local").appName("test").enableHiveSupport().getOrCreate()
sc = spark.sparkContext

data = sc.textFile("E:\\Python\\pyspark_demo01\\pyspark_data\\kmeans_data.txt")
# 先处理有用的数据
parsedData = data.map(lambda line: line.split(',')[:4]).map(lambda line: array([float(x) for x in line]))

# 将数据分群
clusters = KMeans.train(parsedData, 4, maxIterations=10, initializationMode="random")

print("将数据分群之后分布规律：{}".format(clusters.centers))


# 计算每个中心点的和  K-means值
def error(point):
    center = clusters.centers[clusters.predict(point)]
    return sqrt(sum([x ** 2 for x in (point - center)]))


WSSSE = parsedData.map(lambda point: error(point)).reduce(lambda x, y: x + y)
print("距离中心的点和：{}".format(str(WSSSE)))

WSSSE_list = []

for k in range(2, 20):
    clusters = KMeans.train(parsedData, k, maxIterations=10, initializationMode="random")
    WSSSE = parsedData.map(lambda point: error(point)).reduce(lambda x, y: x + y)
    WSSSE_list.append(WSSSE)
print("WSSSE_list:{}".format(WSSSE_list))
sns.set_style("darkgrid")
plt.plot(WSSSE_list)
plt.show()
